<template>
  <div class="permission-group">
    <je-panel>
      <je-panel-item>
        <je-tree
          ref="treeview"
          class="table-treeView"
          draggable
          :tree-config="{
            trigger: 'cell-dblclick',
            rowField: 'id',
            parentField: 'parent',
            checkbox: true,
          }"
          :loading="loading"
          size="mini"
          :data="treeData"
          @before-drop="beforedrop"
          @current-change="itemClickEvent"
          @drop="drop"
          @search-select="doSearchChange"
        >
        </je-tree>
      </je-panel-item>
      <je-panel-item region="tbar" v-bind="options.tbar">
        <div>
          <je-toolbar space="0">
            <je-button type="text" @click="showAddPermission = true"
              ><i class="fal fa-user-friends"></i>添加权限组</je-button
            >
            <je-button type="text" :disabled="!disabledDelEdit" @click="del"
              ><i class="fal fa-user-times"></i>删除</je-button
            >
            <je-button type="text" @click="refresh">
              <i class="fal fa-sync"></i>刷新权限缓存
            </je-button>
          </je-toolbar>
        </div>
      </je-panel-item>
      <je-panel-item region="bottom" v-bind="options.bottom">
        <je-collapse v-model:activeKey="activeKey" accordion expand-icon-position="right">
          <je-collapse-panel key="1" header="基本信息">
            <div class="content">
              <je-form
                validate-type="tooltip"
                :model="modelRef"
                :label-col="{ span: 6 }"
                :wrapper-col="{ span: 18 }"
                label-align="right"
                :colon="false"
              >
                <je-form-item
                  name="permissionName"
                  label="权限组名称"
                  v-bind="validateInfos.permissionName"
                >
                  <je-input v-model:value.trim="modelRef.permissionName" :disabled="disabledRow" />
                </je-form-item>
                <je-form-item label="权限组编码" name="code">
                  <je-input v-model:value="modelRef.code" disabled="disabled" />
                </je-form-item>
                <je-button
                  v-show="btnShow"
                  :disabled="disabledRow"
                  class="btn"
                  type="primary"
                  @click="onSubmit"
                  >保存</je-button
                >
              </je-form>
            </div>
          </je-collapse-panel>
        </je-collapse></je-panel-item
      >
    </je-panel>
    <div v-if="showAddPermission">
      <AddPermission v-model:visible="showAddPermission" @addFile="getTreeData" />
    </div>
  </div>
</template>

<script>
  import { defineAsyncComponent, defineComponent, onMounted, reactive, ref, watch } from 'vue';

  import { Panel, Form, Button, Modal, Tree } from '@jecloud/ui';

  import { loadPermGroupApi, moveGroupApi, removePermGroupApi, updatePermGroupApi } from '@/api';

  import { Collapse } from 'ant-design-vue';

  import VueEvent from '@/helper/model/event';

  const useForm = Form.useForm;

  import { verifyData } from '@/utils/validate';

  export default defineComponent({
    name: 'PermissionGroup',
    components: {
      AddPermission: defineAsyncComponent(() => import('./add-permission.vue')),
      JePanel: Panel,
      JePanelItem: Panel.Item,
      JeCollapse: Collapse,
      JeCollapsePanel: Collapse.Panel,
      JeForm: Form,
      JeFormItem: Form.Item,
      JeButton: Button,
      JeTree: Tree,
    },
    setup() {
      const options = reactive({
        // tabr样式
        tbar: {
          size: 40,
          style: {
            borderRight: '1px solid #e6e6e6',
            borderTop: '1px solid #e6e6e6',
            borderBottom: '1px solid #e6e6e6',
          },
        },
        bottom: {
          style: {
            // borderRight: '1px solid #e6e6e6',
          },
        },
      });
      const treeData = ref([]);
      const loading = ref(false);
      onMounted(() => {
        getTreeData();
      });
      // 获取权限组数据
      const treeview = ref('treeview');
      let currentMeta = ''; // 对比项
      // 加载权限组数据
      const getTreeData = (id) => {
        loading.value = true;
        let params = {};
        if (id == 'refresh') {
          params = { refresh: '1' };
        }
        loadPermGroupApi(params).then((res) => {
          treeData.value = res.children;
          loading.value = false;
          // 如果id为flag则表示更新
          if (id === 'flag') {
            setTimeout(() => {
              // 模拟点击操作
              currentId.value = null;
              const row = treeview.value.getRowById(currentMeta);
              treeview.value.setCurrentRow(row);
              itemClickEvent({ row });
            }, 200);
          }
          /* if (id && id !== 'flag') {
            setTimeout(async () => {
              const row = await treeview.value?.getRowById(id); // 得到当前项
              treeview.value.setTreeExpand4Path({ row, expand: true }); // 展开当前项
              treeview.value.setSelectRow(row); // 选中
              itemClickEvent({ row }); // 点击
              setTimeout(() => {
                treeview.value.scrollToRow(row); // 滚动
              }, 200);
            }, 0);
          } */
          if (id == 'refresh') {
            Modal.notice('刷新权限缓存成功！', 'success');
          }
        });
      };

      const modelRef = reactive({
        permissionName: '',
        code: '',
      });

      // 增加权限组显示
      const showAddPermission = ref(false);
      // 每项的点击事件
      let currentId = ref(null);
      // 手风琴的显影项
      const activeKey = ref('0');
      const disabledDelEdit = ref(false); // 删除置灰
      let meta = null;
      let openActiveKey = true; // activeKey开关
      // 点击tree
      const itemClickEvent = ({ row }) => {
        // 1.如果选中项再次被点击
        if (currentId.value === row.id) {
          // 重置数据
          currentId.value = null;
          disabledDelEdit.value = false;
          meta = null;
          modelRef.permissionName = '';
          disabledRow.value = true;
          VueEvent.emit('cleanData');
          resetFields();
        } else {
          // 2.如未被点击
          disabledRow.value = false;
          currentId.value = row.bean.JE_RBAC_PERMGROUP_ID;
          // 显示右侧账户数据
          VueEvent.emit('showAccount', {
            _id: currentId.value,
            _type: 'permissionGroup',
            _nodeType: 'PERM_GROUP',
          });
          // 手风琴展开
          if (openActiveKey) {
            activeKey.value = '1';
            openActiveKey = false;
          }
          disabledDelEdit.value = true;
          modelRef.permissionName = row.bean.PERMGROUP_NAME;
          modelRef.code = row.bean.PERMGROUP_CODE;
          meta = JSON.parse(JSON.stringify(row.bean.PERMGROUP_NAME)); // 更新对比项
        }
      };

      //基本信息中的置灰
      const disabledRow = ref(true);

      // 刷新
      const refresh = () => {
        getTreeData('refresh'); // 获取数据
        treeview.value.clearCurrentRow(); // 清空选中项
        currentId.value = null;
        disabledDelEdit.value = false;
        meta = null;
        modelRef.permissionName = '';
        resetFields(); // 重置表单
        disabledRow.value = true;
        VueEvent.emit('cleanData');
      };

      // 拖动排序
      // 节点的移动：拖动和转移
      const beforedrop = ({ action }) => {
        if (action === 'insert') return false; // 不允许插入
        return true;
      };
      // let _index = null;
      const drop = ({ row }) => {
        let _index = null;
        // 得到index
        _index = treeview.value.getRowIndex(row);
        // 数据更新
        moveGroupApi({
          id: row.id,
          targetIndex: _index,
        }).then((res) => {
          Modal.notice(res, 'success');
        });
      };

      // 验证规则
      const rulesRef = reactive({
        permissionName: verifyData.title,
      });
      const { resetFields, validate, validateInfos } = useForm(modelRef, rulesRef, {
        // onValidate: (...args) => console.log(...args),
      });
      // 点击保存按钮事件
      const onSubmit = () => {
        // 校验成功
        validate().then(() => {
          // 值不空
          if (modelRef.permissionName && modelRef.code) {
            // 值发生改变
            if (modelRef.permissionName !== meta) {
              disabledRow.value = true;
              // 接口更新数据
              updatePermGroupApi({ name: modelRef.permissionName, id: currentId.value }).then(
                (res) => {
                  Modal.notice(res, 'success');
                  disabledRow.value = false;
                  // 修改对比项
                  meta = JSON.parse(JSON.stringify(modelRef.permissionName));
                  currentMeta = JSON.parse(JSON.stringify(currentId.value));
                  currentId.value = null;
                  getTreeData('flag');
                },
              );
            } else {
              Modal.notice('无数据操作!', 'info');
            }
          } else {
            Modal.alert('请先选择权限组', 'info');
          }
        });
        return false;
      };

      // 删除权限组
      const del = () => {
        Modal.confirm('您确定要删除吗？', () => {
          // 有选中才能删除
          if (currentId.value) {
            removePermGroupApi({ id: currentId.value }).then((res) => {
              Modal.notice(res, 'success');
              setTimeout(() => {
                refresh();
                disabledRow.value = true;
                VueEvent.emit('cleanData'); // 还原右侧视图
              }, 200);
            });
          }
        });
      };

      // 关闭按钮优化
      const btnShow = ref(false);
      // 监听activeKey的值
      watch(
        () => activeKey.value,
        (nv) => {
          if (nv === '1') {
            setTimeout(() => {
              options.bottom.size = 200;
              btnShow.value = true;
            }, 150);
          } else {
            options.bottom.size = 40;
            btnShow.value = false;
          }
        },
      );
      //搜索框选中事件
      const doSearchChange = ({ row }) => {
        itemClickEvent({ row });
      };

      return {
        btnShow,
        modelRef,
        validateInfos,
        resetFields,
        onSubmit,
        options,
        treeData,
        loading,
        itemClickEvent,
        currentId,
        treeview,
        showAddPermission,
        activeKey,
        disabledDelEdit,
        del,
        refresh,
        getTreeData,
        drop,
        beforedrop,
        disabledRow,
        doSearchChange,
      };
    },
  });
</script>

<style lang="less" scoped>
  .permission-group {
    width: 100%;
    position: relative;
    .btn {
      position: absolute;
      bottom: 20px;
      left: 50%;
      transform: translate(-50%, 0);
    }
    .active {
      background: #d1e4ff;
      color: #006ed7;
    }
    :deep(.je-toolbar-item .ant-btn) {
      padding: 4px 16px;
    }
    .my-draggable {
      position: relative;
      :deep(.draggabled) {
        padding-left: 20px;
        width: 100%;
        height: 30px;
        line-height: 30px;
        color: #3f3f3f;
        display: flex;
        justify-content: space-between;
        &:hover {
          cursor: pointer;
        }
      }
      .word {
        position: absolute;
        font-size: 14px;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
      }
    }
    :deep(.table-treeView .je-panel-item-region-default) {
      border-right: 1px solid #e6e6e6;
      padding-bottom: 20px;
    }
    :deep(.table-treeView .je-tree-search-wrapper > *) {
      height: 40px;
      .ant-input-clear-icon {
        top: 10px;
      }
    }
    :deep(.table-treeView .ant-input-affix-wrapper.ant-select-selection-search-input) {
      border-top: 1px solid #ffffff;
      &:hover {
        border-top: 1px solid #5c8dff;
        .ant-input-prefix {
          margin-top: -0.5px;
        }
      }
    }
    :deep(.table-treeView .ant-input-affix-wrapper-focused.ant-select-selection-search-input) {
      border: 1px solid #5c8dff;
    }
    .content {
      padding: 4px;
      height: 130px;
      :deep(.ant-form-item) {
        margin-bottom: 6px;
      }
    }
    :deep(.ant-collapse-header) {
      height: 40px;
      line-height: 15px;
      background: #f7f9fc;
    }
  }
</style>
